package com.plian.system.aspect;

import com.alibaba.fastjson.JSONObject;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.system.annotation.Behavioral;
import com.plian.system.entity.sys.BehavioralData;
import com.plian.system.mapper.sys.SysUserMapper;
import com.plian.system.model.ObjResult;
import com.plian.system.model.R;
import com.plian.system.service.sys.behavioral.IBehavioralDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import java.util.Optional;

/**
 * @Description: TODO
 * @Author: Take-off
 * @Date: 2023/6/8 10:21 AM
 * @Param
 * @return
 * @Version: 1.0
 **/
@Component
@Aspect
@Slf4j
@RequiredArgsConstructor
public class BehavioralAspect {

    private final SysUserMapper userMapper;

    private final IBehavioralDataService behavioralDataService;


    /**
     * 配置切入点
     */
    @Pointcut("@annotation(com.plian.system.annotation.Behavioral)")
    public void behavioralPointcut() {
        // 该方法无方法体,主要为了让同类中其他方法使用此切入点
    }

    @AfterReturning(pointcut = "behavioralPointcut()", returning = "jsonResult")
    public void logAround(JoinPoint joinPoint, Object jsonResult)  {
        BehavioralData behavioralData = new BehavioralData();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 方法名称
        String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
        behavioralData.setMethodName(methodName);
        Behavioral annotation = method.getAnnotation(Behavioral.class);
        String actionTypeId = annotation.actionTypeId();
        String formType = annotation.formType();

        behavioralData.setActionTime(new Date());
        //操作用户
        String userId = TokenUtil.getTokenUserId();
        behavioralData.setUserId(userId);
        String orgId = TokenUtil.getTokenOrgId();
        behavioralData.setOrgId(orgId);
        if (StringUtil.isNotBlank(userId)){
            Optional.ofNullable(userMapper.selectById(userId)).ifPresent(user ->{
                behavioralData.setUserRole(user.getType());
            });
        }
        //单据id
        Object pageData = null;
        if (jsonResult instanceof R){
             pageData = ((R<?>) jsonResult).getPageData();
        }else if (jsonResult instanceof ObjResult){
            pageData = ((ObjResult) jsonResult).getPageData();
        }
        Optional.ofNullable(pageData).ifPresent(pd ->{
            Map map = JSONObject.parseObject(JSONObject.toJSONString(pd), Map.class);
            behavioralData.setFormId(map.get("id").toString());
            if (StringUtil.isNotBlank(formType)){
                behavioralData.setFormType(formType);
            }else {
                Object tempFormType = map.get("formType");
                behavioralData.setFormType(tempFormType != null ? tempFormType.toString() : null);
            }

            if (StringUtil.isNotBlank(actionTypeId)){
                behavioralData.setActionType(Integer.valueOf(actionTypeId));
            }else {
                if (methodName.contains("detail")){
                    behavioralData.setActionType(1);
                }
            }
        });
        behavioralData.setIsDeleted(0);
        behavioralDataService.save(behavioralData);
    }
}
